
package com.dream.utils.system.cfg;

import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dream.utils.date.DateParseUtils;
import com.dream.utils.io.FileIOUtils;

/**
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2012/09/01
 */
public class SystemConfigUtils {

	/**
	 * property file keys
	 * @author Administrator
	 *
	 */
	private static final class Key{
		public static final String SYSTEM_DB = "system.db";
		public static final String SYSTEM_ROOT = "system.root";
		public static final String SYSTEM_DEV = "system.dev";
	}
	
	/**
	 * system configuration file
	 * @author evan
	 *
	 */
	private static final class File{
		public static final String SYSTEM_BASE_PROPERTY = "system-base.properties";
		public static final String SYSTEM_BASE_CONFIGURATION = "configuration-base.xml";
	}
	
	private static Log log = LogFactory.getLog(SystemConfigUtils.class);
	
	/**
	 * @copyright evan
	 * @author evan
	 * @Revision
	 * @date 2012/09/01
	 */
	private static class MyInstatnce {

		private static final SystemConfigUtils instance = new SystemConfigUtils();
	}

	private  Properties properties = new Properties();

	private  XMLConfiguration config = null;


	public static SystemConfigUtils instance() {

		return MyInstatnce.instance;
	}

	private SystemConfigUtils() {

		load();
	}

	private void load() {
		
		InputStream in = null;
		try {
			in = FileIOUtils.fileInputStream(File.SYSTEM_BASE_PROPERTY);
			properties.load(in);

		}catch (Exception e) {
			log.error(this.getClass().getName(), e);
			throw new RuntimeException(e);
		} finally {
			FileIOUtils.close(in);
		}

		try {
			config = new XMLConfiguration(File.SYSTEM_BASE_CONFIGURATION);

		} catch (ConfigurationException e) {
			log.error(this.getClass().getName(), e);
			throw new RuntimeException(e);
		}
		
	}

	/**
	 * Gets the value.
	 * 
	 * @param key
	 *            the key
	 * @return the value
	 */
	public String getValue(String key) {

		return getValue(key, "");

	}

	/**
	 * 
	 * @param key
	 * @param defaultVal
	 * @return
	 */
	public String getValue(String key, String defaultVal) {

		String values = "";

		if (config.containsKey(key)) {
			values = config.getString(key);
		} else {
			values = properties.getProperty(key);
		}

		if (StringUtils.isBlank(values)) {
			values = defaultVal;
		}

		return values;
	}

	/**
	 * Gets the long.
	 * 
	 * @param key
	 *            the key
	 * @return the long
	 */
	public Long getLong(String key,Long defVal) {

		try {
			String val = getValue(key, Long.toString(defVal));
			return Long.parseLong(val);
		} catch (Exception e) {
			log.error(e);
			return defVal;
		}

	}

	/**
	 * 
	 * @param key
	 * @return
	 */
	public List<Object> getList(String key) {

		return config.getList(key);
	}


	/**
	 * 
	 * 
	 * @param key
	 * @param dftValue
	 * @return
	 */
	public Integer getInteger(String key, int dftValue) {

		try {
			String val = getValue(key, Integer.toString(dftValue));
			return Integer.parseInt(val);
		} catch (Exception e) {
			log.error(e);
			return dftValue;
		}
		

	}

	/**
	 * Gets the boolean.
	 * 
	 * @param key
	 *            the key
	 * @return the boolean
	 */
	public boolean getBoolean(String key) {

		String vals = getValue(key, "false");

		try {
			return Boolean.valueOf(vals);
		} catch (Exception e) {
			log.error(e);
			return false;
		}
	}

	/**
	 * Gets the float.
	 * 
	 * @param key
	 *            the key
	 * @return the float
	 */
	public Float getFloat(String key) {

		return Float.valueOf(getValue(key));
	}

	/**
	 * Gets the date.
	 * 
	 * @param key
	 *            the key
	 * @return the date
	 */
	public Date getDate(String key) {

		return DateParseUtils.parseDate(getValue(key));
	}

	/**
	 * Gets the values.
	 * 
	 * @param key
	 *            the key
	 * @return the values
	 */
	public String[] getValues(String key) {

		return properties.getProperty(key).split(",");
	}

	/**
	 * Checks if is dev mode.
	 * 
	 * @return true, if is dev mode
	 */
	public boolean isDevMode() {

		String dev = getValue(Key.SYSTEM_DEV);

		if (StringUtils.isBlank(dev)) {
			return false;
		} else {
			return getBoolean(Key.SYSTEM_DEV);
		}

	}
	
	/**
	 * get system db type
	 * @return
	 */
	public String getSystemDB(){
		return getValue(Key.SYSTEM_DB);
	}
	
	/**
	 * get system root path
	 * @return
	 */
	public String getSystemRoot(String defVal){
		
		return getValue(Key.SYSTEM_ROOT,defVal);
	}
	/**
	 * Gets the properties.
	 * 
	 * @param key
	 *            the key
	 * @param defaultProperties
	 *            the default properties
	 * @return the properties
	 */
	public Properties getProperties(String key) {

		return config.getProperties(key);
	}

	/**
	 * Reload properties.
	 */
	public void reloadProperties() {
		this.properties.clear();
		this.load();
	}

}
